#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from pymongo import MongoClient
from config.settings import settings
import logging

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class MongoGameState:
    def __init__(self, connection_string=settings.MONGODB_URI,
                 database_name=settings.MONGODB_DB_NAME,
                 username=settings.MONGODB_USERNAME,
                 password=settings.MONGODB_PASSWORD):
        try:
            # 构建带认证的客户端
            if username and password:
                # 从连接字符串中提取主机信息，添加认证信息
                self.client = MongoClient(
                    connection_string,
                    username=username,
                    password=password,
                    authSource=database_name
                )
            else:
                # 不使用认证的连接（仅用于开发环境）
                self.client = MongoClient(connection_string)

            self.db = self.client[database_name]
            self.users_collection = self.db.res_user
            self.tokens_collection = self.db.access_token

            # 创建索引以提高查询性能
            self.users_collection.create_index("user_id", unique=True)
            self.tokens_collection.create_index("token", unique=True)
            self.tokens_collection.create_index("expires_at", expireAfterSeconds=0)  # 自动过期

            logging.info("MongoDB连接成功")
        except Exception as e:
            logging.error(f"MongoDB连接失败: {e}")
            self.client = None

    def save_user(self, user_id, user_data):
        """保存玩家数据到MongoDB"""
        if not self.client:
            return False

        try:
            user_doc = {
                "user_id": user_id,
                "data": user_data
            }

            # 使用upsert操作，如果存在则更新，不存在则插入
            result = self.users_collection.replace_one(
                {"user_id": user_id},
                user_doc,
                upsert=True
            )
            return True
        except Exception as e:
            logging.error(f"保存玩家数据失败: {e}")
            return False

    def load_user(self, user_id):
        """从MongoDB加载玩家数据"""
        if not self.client:
            return None

        try:
            user_doc = self.users_collection.find_one({"user_id": user_id})
            if user_doc:
                return user_doc["data"]
            return None
        except Exception as e:
            logging.error(f"加载玩家数据失败: {e}")
            return None

    def save_token(self, token, token_data):
        """保存token信息到MongoDB"""
        if not self.client:
            return False

        try:
            token_doc = {
                "token": token,
                "data": token_data
            }

            # 使用upsert操作
            result = self.tokens_collection.replace_one(
                {"token": token},
                token_doc,
                upsert=True
            )
            return True
        except Exception as e:
            logging.error(f"保存token失败: {e}")
            return False

    def load_token(self, token):
        """从MongoDB加载token信息"""
        if not self.client:
            return None

        try:
            token_doc = self.tokens_collection.find_one({"token": token})
            if token_doc:
                return token_doc["data"]
            return None
        except Exception as e:
            logging.error(f"加载token失败: {e}")
            return None

    def delete_token(self, token):
        """从MongoDB删除token"""
        if not self.client:
            return False

        try:
            result = self.tokens_collection.delete_one({"token": token})
            return result.deleted_count > 0
        except Exception as e:
            logging.error(f"删除token失败: {e}")
            return False

    def update_user_position(self, user_id, x, y):
        """更新玩家位置"""
        if not self.client:
            return False

        try:
            result = self.users_collection.update_one(
                {"user_id": user_id},
                {"$set": {"data.x": x, "data.y": y}}
            )
            return result.modified_count > 0 or result.upserted_id is not None
        except Exception as e:
            logging.error(f"更新玩家位置失败: {e}")
            return False

    def add_item_to_user(self, user_id, item):
        """为玩家添加物品"""
        if not self.client:
            return False

        try:
            # 确保玩家存在
            user_data = self.load_user(user_id)
            if not user_data:
                user_data = {"x": 0, "y": 0, "inventory": []}

            if "inventory" not in user_data:
                user_data["inventory"] = []

            user_data["inventory"].append(item)

            return self.save_user(user_id, user_data)
        except Exception as e:
            logging.error(f"添加物品失败: {e}")
            return False

    def get_all_users(self):
        """获取所有玩家数据"""
        if not self.client:
            return []

        try:
            users = []
            cursor = self.users_collection.find()
            for doc in cursor:
                users.append({
                    "user_id": doc["user_id"],
                    "data": doc["data"]
                })
            return users
        except Exception as e:
            logging.error(f"获取所有玩家数据失败: {e}")
            return []

    def find_user_by_openid(self, openid):
        """
        根据openid查找玩家数据
        @param openid: 微信用户唯一标识
        @return: 玩家数据或None
        """
        if not self.client or not openid:
            return None

        try:
            # 在users集合中查找data.profile.openid匹配的文档
            user_doc = self.users_collection.find_one({
                "data.profile.openid": openid
            })

            if user_doc:
                return user_doc["data"]
            return None
        except Exception as e:
            logging.error(f"根据openid查找玩家失败: {e}")
            return None

    def close(self):
        """关闭数据库连接"""
        if self.client:
            self.client.close()
